/**
 *  axios 封装
 * 请求拦截、响应拦截、错误统一处理
 */
import axios from "axios";
import { message } from "ant-design-vue";
import router from "@/router";

// 请求地址在 vue 的入口文件声明 可由配置文件配置

// 请求超时时间
axios.defaults.timeout = 1000000;
// post请求头
axios.defaults.headers.post['Content-Type'] = "application/json";
// 允许axios请求携带cookie等凭证
axios.defaults.withCredentials = true;
// 请求拦截器
axios.interceptors.request.use(
    async config => {
        // 每次发送请求之前判断是否存在token
        const token = localStorage.getItem("token")
        const userName = localStorage.getItem('userName')
        if (token) config.headers['token'] = token
        if (userName) {
            config.headers['Ks-Identity'] = await window.versions.getEncrypt(userName)
            config.headers["Client-Time"] = new Date().getTime()
        }
        config.headers['Ks-AppName'] = "electron"
        return config;
    },
    error => {
        return Promise.error(error);
    }
)
// 响应拦截器
axios.interceptors.response.use(
    response => {
        let token = response.headers["token"];
        if (token) {
            localStorage.setItem("token", token)
            window.versions.getToken(token)
        }
        // 返回值为blob的特殊情况
        if (response.headers['content-type'] &&
            (response.headers['content-type'].search('octet/stream') > -1 ||
                response.headers['content-type'].search('octet-stream') > -1 ||
                response.headers['content-type'].search('application/pdf') > -1)) {
            return response.data;
        }
        if (response.status === 200 && (response.data.msg === 'SUCCESS' || response.data.msg === 'success')) {
            return Promise.resolve(response.data);
        } else {
            return Promise.reject(response.data);
        }
    },
    // 服务器状态码不是200的情况
    error => {
        if (error.response) {
            switch (error.response.status) {
                // 401: 未登录
                // 未登录则跳转登陆页面，并携带当前页面路径
                // 登陆成功后返回当前页，这一步需要在登录页操作
                case 401:
                    message.destroy();
                    message.error('请先登录');
                    router.push({ name: 'login' });
                    break;
                // 403 token过期                
                // 登录过期对用户进行提示                
                // 清除本地token和清空vuex中token对象                
                // 跳转登录页面
                case 403:
                    if (router.currentRoute._value.fullPath !== '/login') {
                        message.destroy();
                        message.error('登陆过期，请重新登录');
                    }
                    // 跳转登陆页面，携带当前页面链接
                    router.push({ name: 'login' });
                    break;
                // 404请求地址不存在
                case 404:
                    message.destroy();
                    message.error(error.response.data?.msg ?? error.response?.msg ?? "网络请求不存在");
                    break;
                case 500:
                    message.destroy();
                    message.error(error.response.data?.msg ?? error.response?.msg ?? "服务错误，请确认后台服务通讯是否正常！");
                    break;
                // 其他错误，直接抛出错误提示
                default:
                    // 避免同时出现多个消息提示弹窗
                    message.destroy();
                    message.error(error.response.data?.msg ?? error.response?.msg ?? "未知错误");
                    break;
            }
            return Promise.reject(error.response);
        }
    }
)

const request = {
    // GET 请求
    get: (url, params) => {
        return new Promise((resolve, reject) => {
            axios.get(url, {
                params: params
            })
                .then(res => {
                    resolve(res.data);
                })
                .catch(err => {
                    reject(err);
                })
        })
    },
    // GET 请求 返回二进制大型对象流(blob)
    getBlob: (url, params) => {
        return new Promise((resolve, reject) => {
            axios.get(url, {
                params: params,
                responseType: "blob", //设置返回类型为二进制大型对象流(blob)
            })
                .then(res => {
                    resolve(res);
                })
                .catch(err => {
                    reject(err);
                })
        })
    },
    // POST 请求
    post: (url, params) => {
        return new Promise((resolve, reject) => {
            axios.post(url, params)
                .then(res => {
                    resolve(res.data);
                })
                .catch(err => {
                    reject(err);
                })
        })
    },
    // // POST 请求 返回二进制大型对象流(blob)
    postBlob: (url, params) => {
        return new Promise((resolve, reject) => {
            axios.post(url, params, {
                responseType: "blob", //设置返回类型为二进制大型对象流(blob)
            })
                .then(res => {
                    resolve(res);
                })
                .catch(err => {
                    reject(err);
                })
        })
    },
}

export default request
